// 自定义类型

// Exclude Extract集合的操作
// Pick Omit 对对象结构的操作
// Partial Required Readonly  起修饰作用的
// ReturnType Paramaters InstanceType ... (基于infer)

// 这个挺有用的
type Compute<T extends object>={
    [K in keyof T]:T[K] //映射
}
// 让部分属性  变为可选属性  怎么办？
interface Person{
    name:string,
    age:number,
    company:string
}
// 先将name属性挑出来变为可选的  & 除了name属性的
type PartialPropsOptional<T,K extends keyof T> = Partial<Pick<T,K>> & Omit<T,K>

type x =Compute<PartialPropsOptional<Person,'name'>> 

// 以前根据key 来选属性
// 根据值的类型 来选择key
type isEqual<T,U,Success,Fail> = [T] extends [U]
? [U] extends [T]
 ? Success
 :Fail
 :Fail
type ExtractKyesByValueType<T,U,O=false>={
    // [K in keyof T ] : isEqual<T[K],U,K,never>
    [K in keyof T ] : isEqual<T[K],U,isEqual<O,true,never,K>,isEqual<O,true,K,never>>
}[keyof T]
// interface P{
//     name:'a',
//     age:'b'
// }
// type x = P[keyof P]
type PickKeysByValue<T,U> =Pick<T,ExtractKyesByValueType<T,U,false>>
type x2 = PickKeysByValue<Person,string>

// 如果是Omit如何编写？
// type OmitKyesByValueType<T,U>={
//     [K in keyof T ] : isEqual<T[K],U,never,K>
// }[keyof T]
// type OmitKeysByValue<T,U> =Pick<T,OmitKyesByValueType<T,U>>
type OmitKeysByValue<T,U> =Pick<T,ExtractKyesByValueType<T,U,true>>
type x3 = OmitKeysByValue<Person,string>


// 重映射----最终优化    场景  模板字符串
type PickKeysByValue1<T extends object,U> ={
    // 这里的as不是断言了  是重命名的意思 
    [K in keyof T as T[K] extends U ? K : never] : T[K]
}
type x4 = PickKeysByValue1<Person,string>

export{}